/**
 * @module ChiVoxSDK/html5
 * @author Don Li <kai.li@chivox.com>
 * @licence
 * Copyright (c) 2017 - 2020 ChiVox Inc. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

import Utils from '../utils';
import {
    tts
} from '../lib/public';

/**
 * HTML5模式的播放器。<br/><br/>
 *
 * 基于AudioContext技术设计开发，用于支持该环境下的远程音频播放。
 */
export class Html5Player {
    /**
     * 创建一个Html5音频播放器。
     * @param {Object} options - 初始化参数。格式参见：{@link Default_ChiVoxPlayer_Options}
     */
    constructor(options) {
        this.options = options;
        let AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;

        this.ctx = new AudioContext();
        if (this.ctx) {
            this.src = this.ctx.createBufferSource();
            this.gain = this.ctx.createGain();

            this.gain.connect(this.ctx.destination);

            this.buff = null;
            this.tts = tts;

            if (this.options.onInit)
                this.options.onInit();

            this.can_play = true;
            this.loaded = true;
        }
    }

    /**
     * 远程加载音频。
     *
     * @param {Object} options - 加载音频所需的参数。参数有：
     * @param {string} options.url - 要加载的音频URL地址。
     * @param {callback} options.success - 加载音频成功的Callback，格式：() => {}。
     * @param {callback} options.error - 加载音频失败后的Callback，格式：(err) => {}。
     */
    load(options) {
        if (!options.hasOwnProperty('url') || options.url == "") {
            if (options.hasOwnProperty("error")) {
                options.error('param: url is missing!');
            }
            return;
        }

        let req = new XMLHttpRequest();
        req.open('GET', options.url, true);
        req.responseType = 'arraybuffer';

        req.onload = () => {
            if (req.status !== 200) {
                if (options.hasOwnProperty("error")) {
                    options.error("url:" + options.url + "不存在，获取失败。 status: " + req.status);
                }

                return;
            }

            this.ctx.decodeAudioData(req.response,
                (data) => {
                    this.buff = data;
                    if (options.hasOwnProperty("success")) {
                        options.success();
                    }
                },
                (err) => {
                    if (options.hasOwnProperty("error")) {
                        options.error(err);
                    }
                }
            );
        };

        req.send();
    }

    /**
     * 播放已经加载的音频。
     *
     * @param {Object} options - 播放音频所需的参数。参数有：
     * @param {int=} options.position - 播放位置，默认0。
     * @param {int=} options.duration - 播放时长。
     * @param {callback} options.onStart - 开始播放音频时的Callback，格式：(code, message) => {}。
     * @param {callback} options.onStop - 音频播放完成后的Callback，格式：(code, message) => {}。
     */
    play(options) {
        if (this.buff && this.ctx) {
            this.src = this.ctx.createBufferSource();
            this.src.connect(this.gain);
            this.src.buffer = this.buff;
            this.src.start(0);

            this.src.onended = function() {
                this.src = null;
                if (options.hasOwnProperty("onStop")) {
                    options.onStop();
                }
            };

            if (options.hasOwnProperty("onStart")) {
                options.onStart();
            }
        } else {
            if (this.options.onError) {
                this.options.onError('play failed. buff or ctx is null.', this.buff, this.ctx);
            }
        }
    }

    /**
     * 手动停止音频播放。
     */
    stop(onStop, force = false) {
        if (this.src && this.src.onended != null) {
            this.src.stop();
            this.src = null;
        }

        if (!force) {
            console.debug('[ AiPlayerH5.stop ]...');
            if (onStop) {
                onStop();
            }
        }
    }

    /**
     * 重置播放器状态。
     */
    reset() {
        this.stop(null, true);
    }

    /**
     * 设置播放器播放音量。
     * @param {int} volume - 要设置的音量。 0 ~ 1
     */
    setVolume(volume) {
        if (this.gain) {
            this.gain.connect(this.ctx.destination);
            this.gain.gain.value = volume;
        } else {
            this.options.onError("context or gain is null");
        }
    }

    /**
     * 返回播放器播放音量。
     * @result {int} - 播放器当前音量。 0 ~ 1
     */
    getVolume() {
        if (this.gain) {
            this.gain.connect(this.ctx.destination);
            return this.gain.gain.value;
        } else {
            this.options.onError("context or gain is null");
            return 0.0;
        }
    }

    getDuration() {}
    getPosition() {}
}

export default Html5Player
